﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Web.Script.Serialization;

namespace MyCommon
{
    /// <summary>
    /// 该自定义转换器识别类型成员上的DataMemberAttribute和IgnoreDataMemberAttribute装饰属性
    /// </summary>
    public class DataContractJavaScriptConverter : JavaScriptConverter
    {
        List<Type> m_supportedTypes;
        /// <summary>
        /// 构造DataContractJavaScriptConverter
        /// </summary>
        /// <param name="supportedTypes">支持的类型</param>
        public DataContractJavaScriptConverter(IEnumerable<Type> supportedTypes)
        {
            m_supportedTypes = new List<Type>(supportedTypes);
        }
        /// <summary>
        /// 对序列化
        /// </summary>
        /// <param name="dictionary">数据字典</param>
        /// <param name="type">数据类型</param>
        /// <param name="serializer">序列化工具类实例</param>
        /// <returns></returns>
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            var obj = Activator.CreateInstance(type);
            var properties = type.GetProperties();
            foreach (var prop in properties)
            {
                var attr = Attribute.GetCustomAttribute(prop, typeof(DataMemberAttribute)) as DataMemberAttribute;
                if (dictionary.Keys.Contains(attr.Name))
                {
                    prop.SetValue(obj, dictionary[attr.Name], null);
                }
                else if (dictionary.Keys.Contains(prop.Name))
                {
                    prop.SetValue(obj, dictionary[prop.Name], null);
                }
            }
            return obj;
        }
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="obj">要序列化的对象</param>
        /// <param name="serializer">序列化工具类实例</param>
        /// <returns></returns>
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            var dic = new Dictionary<string, object>();
            var type = obj.GetType();
            var properties = type.GetProperties();
            foreach (var prop in properties)
            {
                var attributes = Attribute.GetCustomAttributes(prop);
                if (attributes.Any(m => m is IgnoreDataMemberAttribute))
                {
                    break;
                }
                var attr = attributes.SingleOrDefault(m => m is DataMemberAttribute) as DataMemberAttribute;
                if (attr != null)
                {
                    dic[attr.Name] = prop.GetValue(obj, null);
                }
                else
                {
                    dic[prop.Name] = prop.GetValue(obj, null);
                }
            }
            return dic;
        }

        /// <summary>
        /// 支持的类型
        /// </summary>
        public override IEnumerable<Type> SupportedTypes
        {
            get { return m_supportedTypes; }
        }
    }
}
